package com.zpark.it.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zpark.it.clients.*;
import com.zpark.it.mapper.PictureMapper;
import com.zpark.it.mapper.ProductMapper;
import com.zpark.it.param.ProductHotParam;
import com.zpark.it.param.ProductIdsParam;
import com.zpark.it.param.ProductSaveParam;
import com.zpark.it.param.ProductSearchParam;
import com.zpark.it.pojo.Picture;
import com.zpark.it.pojo.Product;
import com.zpark.it.service.ProductService;
import com.zpark.it.to.OrderToProduct;
import com.zpark.it.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.stereotype.Service;


import java.util.*;
import java.util.stream.Collectors;

/**
 * @Title: ProductServiceImpl
 * @Author Charles
 * @Package com.zpark.it.service.impl
 * @Date 2023/7/21 15:02
 */
@Service
@Slf4j
public class ProductServiceImpl extends ServiceImpl<ProductMapper,Product> implements ProductService {

    //引入feign客户端需要在启动类上添加配置注解
    @Autowired
    private CategoryClient categoryClient;

    //引入搜索服务客户端
    @Autowired
    private SearchClient searchClient;

    @Autowired
    private ProductMapper productMapper;

    @Autowired
    private PictureMapper pictureMapper;

    @Autowired
    private OrderClient orderClient;

    @Autowired
    private CollectClient collectClient;

    @Autowired
    private CartClient cartClient;

    /**
     * 根据单类名称查询热门商品，至多7条数据
     * 成功继续根据类别id查询商品数据，热门、销售量倒序、查询7条数据
     * 结果封装返回
     *
     * @param categoryName
     * @return
     */
    @Override
    @Cacheable(value = "list.product",key = "#categoryName",cacheManager = "cacheManagerDay")
    public R promo(String categoryName) {

        R r = categoryClient.byName(categoryName);

        if (r.getCode().equals(R.FAIL_CODE)) {
            log.info("ProductServiceImpl.promo业务结束，结果:{}","类别查询失败!");
            return r;
        }

        // 类别服务中 data = category --- feign {json}  ----- product服务 LinkedHashMap jackson

        LinkedHashMap<String,Object>  map = (LinkedHashMap<String, Object>) r.getData();

        Integer categoryId = (Integer) map.get("category_id");

        //封装查询参数
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category_id",categoryId);
        queryWrapper.orderByDesc("product_sales");

        IPage<Product> page = new Page<>(1,7);

        //返回的是包装数据! 内部有对应的商品集合,也有分页的参数 例如: 总条数 总页数等等
        page = productMapper.selectPage(page, queryWrapper);

        List<Product> productList = page.getRecords(); //指定页的数据
        long total = page.getTotal(); //获取总条数

        log.info("ProductServiceImpl.promo业务结束，结果:{}",productList);

        return R.ok("数据查询成功",productList);
    }

    /**
     * 多类别热门商品查询，根据类别名称集合！最后查询7条数据
     * 1、调用类别服务
     * 2、类别集合id查询商品
     * 3、结果封装返回
     * @param productHotParam
     * @return
     */
    @Override
    @Cacheable(value = "list.product",key = "#productHotParam.categoryName")
    public R hots(ProductHotParam productHotParam) {

        R r = categoryClient.hots(productHotParam);

        if(r.getCode().equals(R.FAIL_CODE)){
            log.info("ProductServiceImpl.hots业务结束，结果:{}",r.getMsg());
            return r;
        }

        List<Object> ids = (List<Object>) r.getData();

        //进行商品数据查询
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("category_id",ids);
        queryWrapper.orderByDesc("product_sales");

        IPage<Product> page = new Page<>(1,7);

        page = productMapper.selectPage(page,queryWrapper);

        List<Product> records = page.getRecords();

        R ok = R.ok("多类别热门商品查询成功!", records);

        log.info("ProductServiceImpl.hots业务结束，结果:{}",ok);

        return ok;
    }

    /**
     * 查询类别商品集合
     *
     * @return
     */
    @Override
    public R clist() {
        R r = categoryClient.list();
        log.info("ProductServiceImpl.clist业务结束，结果:{}",r);

        return r;
    }

    /**
     * 通用性的业务
     * 传入了类别id，根据id查询数据，并进行分页
     * 如果没有传入类别id，查询全部
     *
     * @param productIdsParam
     * @return
     */
    @Override
    @Cacheable(value = "list.product",key = "#productIdsParam.categoryID+'-'+#productIdsParam.currentPage+'-'+#productIdsParam.pageSize")
    public R byCategory(ProductIdsParam productIdsParam) {

        List<Integer> categoryID = productIdsParam.getCategoryID();

        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        if (!categoryID.isEmpty()) {
            queryWrapper.in("category_id",categoryID);
        }

        IPage<Product> page = new Page<>(productIdsParam.getCurrentPage(),productIdsParam.getPageSize());

        page = productMapper.selectPage(page,queryWrapper);

        //结果集封装
        R ok = R.ok("查询成功!", page.getRecords(), page.getTotal());

        log.info("ProductServiceImpl.byCategory业务结束，结果:{}",ok);

        return ok;
    }

    /**
     * 根据商品id查询商品详情信息
     *
     * @param productID
     * @return
     */
    @Cacheable(value = "product",key = "#productID")
    @Override

    public R detail(Integer productID) {
        Product product = productMapper.selectById(productID);
        R ok = R.ok(product);
        log.info("业务结束：{}",ok);
        return ok;
    }

    /**
     * 查询商品图片详情信息
     *
     * @param productID
     * @return
     */
    @Override
    @Cacheable(value = "picture",key = "#productID")
    public R pictures(Integer productID) {
        QueryWrapper<Picture> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("product_id",productID);

        List<Picture> pictureList = pictureMapper.selectList(queryWrapper);

        R ok = R.ok(pictureList);

        log.info("结果为：{}",ok);

        return ok;
    }

    /**
     * 搜索服务调用，获取全部商品数据，进行数据同步
     *
     * @return
     */
    @Override
    @Cacheable(value = "list.category",key = "#root.mythodName",cacheManager = "cacheManagerDay")
    public List<Product> allList() {
        List<Product> productList = productMapper.selectList(null);

        log.info("结果为：{}",productList.size());
        return productList;
    }

    /**
     * 搜索业务，需要调用搜索服务
     *
     * @param productSearchParam
     * @return
     */
    @Override
    public R search(ProductSearchParam productSearchParam) {

        R r = searchClient.search(productSearchParam);
        log.info("业务完成：{}",r);
        return r;
    }

    /**
     * 根据商品id集合，查询商品集合信息
     *
     * @param productIds
     * @return
     */
    @Cacheable(value = "list.product",key = "#productIds")
    @Override
    public R ids(List<Integer> productIds) {

        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();

        queryWrapper.in("product_id",productIds);
        List<Product> productList = productMapper.selectList(queryWrapper);

        R r = R.ok("类别查询成功", productList);
        log.info("业务结束：{}", r);
        return r;
    }

    /**
     * 根据商品id查询商品id集合，不包装
     *
     * @param productIds
     * @return
     */
    @Override
    public List<Product> cartList(List<Integer> productIds) {

        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        queryWrapper.in("product_id",productIds);

        List<Product> productList = productMapper.selectList(queryWrapper);
        log.info("业务结束：{}",productList);
        return productList;
    }

    /**
     * 修改库存和增加销售量
     *
     * @param orderToProducts
     */
    @Override
    public void subNumber(List<OrderToProduct> orderToProducts) {
        //将集合转为map
        Map<Integer, OrderToProduct> map = orderToProducts.stream().collect(Collectors.toMap(OrderToProduct::getProductId, v -> v));

        //获取商品的id集合
        Set<Integer> productIds = map.keySet();
        //查询集合对应的商品信息
        List<Product> productList = productMapper.selectBatchIds(productIds);
        //修改商品信息
        for (Product product : productList) {
            Integer num = map.get(product.getProductId()).getNum();
            product.setProductNum(product.getProductNum()-num); //减库存
            product.setProductSales(product.getProductSales()+num);//加销量


        }
        //批量更新
        this.updateBatchById(productList);
        log.info("业务结束，结果为库存和销量修改完成");
    }

    /**
     * 类别对应的商品数量查询
     *
     * @param categoryId
     */
    @Override
    public Long adminCount(Integer categoryId) {

        QueryWrapper<Product> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("category_id",categoryId);

        Long count = baseMapper.selectCount(queryWrapper);
        return count;
    }

    /**
     * 商品保存
     * 1、商品数据保存
     * 2、商品的图片详情切割和保存
     * 3、搜索数据库的数据添加
     * 4、清空商品相关的缓存数据
     * @param productSaveParam
     * @return
     */
    @Override
    @CacheEvict(value = "list.product",allEntries = true)
    public R adminSave(ProductSaveParam productSaveParam) {

        Product product=new Product();
        BeanUtils.copyProperties(productSaveParam,product);

        int rows = productMapper.insert(product);

        //商品图片获取
        String pictures = productSaveParam.getPictures();

        if (!StringUtils.isEmpty(pictures)) {
            //截取特殊字符串的时候 // [] 包含 $ + * / ?
            String[] urls = pictures.split("\\+");
//            List<Picture> pictureList=new ArrayList<>();
            for (String url : urls) {
                Picture picture=new Picture();
                picture.setId(product.getProductId());
                product.setProductPicture(url);
                pictureMapper.insert(picture);//插入商品的图片
            }

        }
        //同步搜索服务的数据
        searchClient.saveOrUpdate(product);
        return R.ok("商品数据添加成功");
    }

    /**
     * 1、更新商品
     * 2、同步es库
     * @param product
     * @return
     */
    @Override
    public R adminUpdate(Product product) {

        productMapper.insert(product);
        searchClient.saveOrUpdate(product);

        return R.ok("商品更新成功");

    }

    /**
     * 商品删除
     *  1、检查购物车
     *  2、检查订单
     *  3、删除商品
     *  4、删除商品相关的图片
     *  5、删除收藏
     *  6、进行es数据同步
     *  7、清空缓存
     * @param productId
     * @return
     */
    @Override
    @Caching(
            evict = {
                    @CacheEvict(value = "list_product",allEntries = true),
                    @CacheEvict(value = "product",key = "#productId")
            }
    )
    public R adminRemove(Integer productId) {
        //1.检查购物车是否存在
        R r = cartClient.check(productId);

        if ("004".equals(r.getCode())) {
            log.info("ProductServiceImpl.remove结束,{}", r.getMsg());
            return r;
        }

        //2.简单账单是否存在
        R or = orderClient.check(productId);
        if ("004".equals(or.getCode())) {
            log.info("ProductServiceImpl.remove结束,{}", or.getMsg());
            return or;
        }

        //删除商品图片详情
        QueryWrapper<Picture> wrapper = new QueryWrapper<>();
        wrapper.eq("product_id", productId);
        pictureMapper.delete(wrapper);
        //删除收藏中的商品
        collectClient.remove(productId);

        //同步数据
        searchClient.remove(productId);
        return R.ok("商品删除成功");

    }


}
